home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
language
/
embedded
/
develop
/
libsrc11.arc
/
FREE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-04-27
|
4KB
|
172 lines
/* free.c 4.4 */
/*M****************************************************************************
MODULE NAME: free
DESCRIPTION: This module has the free function and the malloc function.
******************************************************************************/
#include <hc11/directives.h>
/************************************************/
/* Structures for Free and Malloc */
/************************************************/
typedef int ALIGN; /* align on word boundary */
union header { /* free block header */
struct {
union header *ptr; /* next free block */
unsigned size; /* size of this free block */
} s;
ALIGN x; /* force alignment of blocks */
};
typedef union header HEADER;
#define HDR_SIZE 4 /* size of the HEADER structure */
#define NULL 0 /* null pointer */
/************************************************/
/* static variable for Free and Malloc */
/************************************************/
static HEADER base; /* empty list to get started with */
static HEADER *allocp = NULL; /* last allocated block */
/************************************************/
/* moreRAM */
/* */
/* Lops off a chunk of RAM since there */
/* are no appropriately sized pieces */
/* in the fragmented free space (linked */
/* list). */
/************************************************/
SMALL
static HEADER *moreRAM ( chunk_units )
unsigned chunk_units ;
#define NALLOC HDR_SIZE /* number of units to allocate at once */
{
extern unsigned l__STKLO ; /* start of free space */
static unsigned free_start = NULL ;
HEADER * chunk_ptr ; /* must be last local variable */
if (free_start == NULL)
free_start = (unsigned) &l__STKLO ;
#ifdef HDR_SIZE = 4
chunk_units = chunk_units << 2 ;
#else
chunk_units = chunk_units * HDR_SIZE ;
#endif
if (free_start + chunk_units >= (unsigned) (&chunk_ptr) - 4)
return ( (HEADER *) NULL ) ; /* grew into stack... */
if ( (chunk_units >> 8) + (free_start >> 8) > 255 )
return ( (HEADER *) NULL ) ; /* wrapped around memory */
chunk_ptr = (HEADER *) free_start ;
chunk_ptr->s.size = chunk_units ;
free ( (char *) (chunk_ptr + 1) ) ;
return (allocp) ;
} /* end of moreRAM */
/************************************************/
/* Malloc function */
/************************************************/
SMALL
char *malloc ( nbytes ) /* general purpose storage allocator */
unsigned nbytes ;
{
HEADER *p,*q ;
int nunits ;
#ifdef HDR_SIZE=4
nunits = 1 + ((nbytes + HDR_SIZE - 1) >> 2) ;
#else
nunits = 1 + ((nbytes + HDR_SIZE - 1)/HDR_SIZE ;
#endif
if ((q = allocp) == NULL)
{ /* no free list */
base.s.ptr = allocp = q = &base ;
base.s.size = 0 ;
}
for ( p = q->s.ptr ; ; q = p, p = p->s.ptr)
{
if ( p->s.size >= nunits )
{ /* big enough */
if ( p->s.size == nunits )
q->s.ptr = p->s.ptr ; /* exactly right */
else /* remove the extra bits... */
{
p->s.size -= nunits ;
p += p->s.size ; /* skip over extra bits */
p->s.size = nunits ;
}
allocp = q ;
return ( (char *) (p+1) ) ;
}
if (p == allocp) /* wrapped around free list */
if ( (p = moreRAM(nunits)) == NULL)
return (NULL) ; /* none left */
} /* end of for loop */
} /* end of malloc */
/************************************************/
/* Free function */
/************************************************/
SMALL
free ( ap ) /* put block ap in free list */
char *ap ;
{
HEADER *p, *q ;
p = (HEADER *) ap - 1 ; /* point to header */
for ( q = allocp ; ! (p > q && p < q->s.ptr) ; q = q->s.ptr )
if ( q >= q->s.ptr && (p > q || p < q->s.ptr) )
break ; /* at one end or other */
if ( p + p->s.size == q->s.ptr) /* joint to upper number */
{
p->s.size += q->s.ptr->s.size ;
p->s.ptr = q->s.ptr->s.ptr ;
}
else
p->s.ptr = q->s.ptr ;
if ( q + q->s.size == p) /* join to lower number */
{
q->s.size += p->s.size ;
q->s.ptr = p->s.ptr ;
}
else
q->s.ptr = p ;
allocp = q ;
} /* end of free */